﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public int size = 20;
        public int width = 0;
        public int height = -20;
        public int snakesize = 3;
        private LinkedList<System.Windows.Forms.PictureBox> snakepic;
        
        
        private Game game= new Game();
        int temp_x = 0, temp_y = 0;
        public Form1()
        {
            Thread recieverThread = new Thread(new ThreadStart(Multi.receive));
            recieverThread.IsBackground = true; // Test with or without the IsBackground property set to TRUE.
            recieverThread.Start();
            
            game= new Game();
            InitializeComponent();
            AdditionnalInitialization();
            //setApple();
            
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.timer1.Interval = game.getSpeed();
            
            game.setCommand(true);//you are allowed to enter a new direction with the keyboard
            //WALLS COLLISION
            if(game.getGameover()==false)
                if (game.getSnake().First.Value.getDirection() == 1 && game.getSnake().First.Value.getX() == 26 || game.getSnake().First.Value.getDirection() == 3 && game.getSnake().First.Value.getX() == 0 || game.getSnake().First.Value.getDirection() == 2 && game.getSnake().First.Value.getY() == 23 || game.getSnake().First.Value.getDirection() == 0 && game.getSnake().First.Value.getY() == 0)
            {
                width = 0;
                height = 0;
                this.timer1.Stop();
                System.Windows.Forms.MessageBox.Show("Game Over");                
                game.setGameover(true);
                resetgame();   
            }

            //SELF BODY COLLISION
            LinkedListNode<SnakePart> node = game.getSnake().First; //access to the data List
            node = node.Next;
            while (node != null)
            {
                if(game.getGameover()==false)
                    if (width != 0 && node.Value.getX() == game.getSnake().First.Value.getX() && node.Value.getY() == game.getSnake().First.Value.getY() || height != 0 && node.Value.getX() == game.getSnake().First.Value.getX() && node.Value.getY() == game.getSnake().First.Value.getY())
                {
                    width  = 0;
                    height = 0;
                    this.timer1.Stop();
                    System.Windows.Forms.MessageBox.Show("Game Over");
                    game.setGameover(true);
                    resetgame();
                }
                node = node.Next;
            }

            //APPLE COLLISION
            if (game.getSnake().First.Value.getX() == game.getApple().getX() && game.getSnake().First.Value.getY() == game.getApple().getY())
                {
                    this.apple.Hide();
                    game.getApple().generateNewApple(game.getSnake());
                    if(game.getSpeed()>30)game.setSpeed(game.getSpeed() - 5);
                    System.Console.Write("SPEED : "+game.getSpeed());
                    //add a new part of snake
                    this.addPartData();//add it as data
                    this.addPartPic();//add the picture
                    game.incScore();
                }
            

                

                this.displayAll();

                node = game.getSnake().Last;
                LinkedListNode<SnakePart> befNode = game.getSnake().First;
                temp_x = befNode.Value.getX();
                temp_y = befNode.Value.getY();

                while (node.Previous != null)
                {

                    node.Value.setX(node.Previous.Value.getX());
                    node.Value.setY(node.Previous.Value.getY());

                    node = node.Previous;


                }


            
                if (game.getSnake().First.Value.getDirection() == 1) game.getSnake().First.Value.setX(game.getSnake().First.Value.getX() + 1);
                if (game.getSnake().First.Value.getDirection() == 3) game.getSnake().First.Value.setX(game.getSnake().First.Value.getX() - 1);
                if (game.getSnake().First.Value.getDirection() == 2) game.getSnake().First.Value.setY(game.getSnake().First.Value.getY() + 1);
                if (game.getSnake().First.Value.getDirection() == 0) game.getSnake().First.Value.setY(game.getSnake().First.Value.getY() - 1);

                this.displayAll();
                this.panel1.Show();

                


            


            //System.Console.Write("\n" + "Position x : " + game.head.getX() + " / y : " + game.head.getY() );
            System.Console.Write("\n" + "Position x/y : " + game.getSnake().First.Value.getX() + "/" + game.getSnake().First.Value.getY()
                + " " + game.getSnake().First.Next.Value.getX() + "/" + game.getSnake().First.Next.Value.getY() + " " + game.getSnake().Last.Value.getX() + "/" + game.getSnake().Last.Value.getY());

        }
        // Handle the KeyDown event to determine the type of character entered into the control. 

        private void displayAll() //graphic part to actualize every moved element
        {
            
            this.scoreLabel.Text = "Score : " + game.getScore();
            //this.scoreLabel.ForeColor = System.Drawing.Color.Black;
            this.scoreLabel.Enabled = true;
            //this.scoreLabel.Show();
            if (this.scoreLabel.Enabled == true) System.Console.Write("\n" + "TRUE");
            else System.Console.Write("\n" + "FALSE");    
            LinkedListNode<System.Windows.Forms.PictureBox> picnode = this.snakepic.First; //access to the pictureBoxList
            LinkedListNode<SnakePart> node = game.getSnake().First; //access to the data List

            //actualize apple's picturebox display
            this.apple.Left = size * game.getApple().getX();
            this.apple.Top = size * game.getApple().getY();
            this.apple.Show();

            while (node != null && picnode != null)
            {
                
                picnode.Value.Left = size * node.Value.getX();
                picnode.Value.Top = size * node.Value.getY();

                if (picnode.Previous == null) picnode.Value.BackColor = System.Drawing.Color.DarkGreen;
                else if (picnode.Next == null) picnode.Value.BackColor = System.Drawing.Color.DarkSlateGray;
                else picnode.Value.BackColor = System.Drawing.Color.Black;

                node = node.Next;
                picnode.Value.Show();
                picnode = picnode.Next;
            }

            
                       
        }
        public void resetgame() //relaunch a new game with default settings
        {
            
            //this.InitializeComponent();
            this.timer1.Start();
            LinkedListNode<System.Windows.Forms.PictureBox> picnode = this.snakepic.First; //access to the pictureBoxList

            while (picnode != null)
            {
                picnode.Value.Hide();
                picnode = picnode.Next;              
            }
            this.snakepic = new LinkedList<System.Windows.Forms.PictureBox>();
            this.snakepic.AddFirst(new System.Windows.Forms.PictureBox());//Head
            this.snakepic.AddLast(new System.Windows.Forms.PictureBox());//First body
            this.snakepic.AddLast(new System.Windows.Forms.PictureBox());//Tail
            picnode = this.snakepic.First;
            int i = 0;
            while (picnode != null)
            {

                if (i == 0) picnode.Value.BackColor = System.Drawing.Color.DarkGreen;
                else if (picnode.Next == null) picnode.Value.BackColor = System.Drawing.Color.DarkSlateGray;
                else picnode.Value.BackColor = System.Drawing.Color.Black;
                picnode.Value.Location = new System.Drawing.Point(260, 240 + 20 * i);
                picnode.Value.Name = "pictureBox" + i;
                picnode.Value.Size = new System.Drawing.Size(20, 20);
                picnode.Value.TabIndex = 0;
                picnode.Value.TabStop = false;
                i++;
                this.panel1.Controls.Add(picnode.Value);
                picnode = picnode.Next;
            }

            Game game= new Game();
                      
            this.game = game;
            this.size = 20;
            this.width = 0;
            this.height = -20;
        }

        public void addPartData() //add a new SnakePart in the data List
        {
            this.game.setSnakesize(this.game.getSnakesize()+1);
            LinkedListNode<SnakePart> node = game.getSnake().First; //access to the data List
            int size = 0;
            while (node.Next != null)
            {
                node = node.Next;
            }
            game.getSnake().Last.Value.setType(1);
            game.getSnake().AddLast(new SnakePart(node.Value.getX(), node.Value.getY(), 2, 0));
            node = game.getSnake().First;
            while (node != null)
            {
                size++;
                node = node.Next;
            }
            System.Console.Write("\n"+"New Part Added / Size : " + size);

        }
        public void addPartPic() //add a new part in the PictureBox List
        {
            LinkedListNode<System.Windows.Forms.PictureBox> picnode = this.snakepic.First; //access to the pictureBoxList
            LinkedListNode<SnakePart> node = game.getSnake().First; //access to the data List
            int i = 0;
            /*while (picnode != null)
            {
                picnode = picnode.Next;
            }*/

            this.snakepic.AddLast(new System.Windows.Forms.PictureBox());

            while (picnode != null && node != null)
            {
                if (picnode.Next == null)
                {
                    picnode.Value.Hide();
                    picnode.Value.BackColor = System.Drawing.Color.DarkSlateGray; 
                    //picnode.Previous.Value.BackColor = System.Drawing.Color.Black;//change the color of the previous part to grey from black
                    //System.Console.Write("\n" + "GETX GETY : " + node.Value.getX() + " " + node.Value.getY());
                    picnode.Value.Location = new System.Drawing.Point(node.Value.getX(), node.Value.getY());
                    picnode.Value.Name = "pictureBox" + i;
                    picnode.Value.Size = new System.Drawing.Size(20, 20);
                    picnode.Value.TabIndex = 0;
                    picnode.Value.TabStop = false;
                    //picnode.Value.Show();
                }                
                i++;
                picnode = picnode.Next;
                node = node.Next;
            }

            picnode = this.snakepic.First;

            while (picnode.Next != null)
            {
                picnode = picnode.Next;
            }


            this.panel1.Controls.Add(picnode.Value);


        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            // Determine whether the keystroke is a backspace. 
            if ((e.KeyCode == Keys.Right) && (game.getSnake().First.Value.getDirection() != 3) && (game.getSnake().First.Value.getDirection() != 1) && (game.getCommand() == true))
            {
                width = 20;
                height = 0;
                //game.head.setDirection(1);
                game.getSnake().First.Value.setDirection(1);
                game.setCommand(false);
                
            }
            if ((e.KeyCode == Keys.Left) && (game.getSnake().First.Value.getDirection() != 1) && (game.getSnake().First.Value.getDirection() != 3) && (game.getCommand() == true))
            {
                width = -20;
                height = 0;
                game.getSnake().First.Value.setDirection(3);
                //game.head.setDirection(3);
                game.setCommand(false);
            }
            if ((e.KeyCode == Keys.Up) && (game.getSnake().First.Value.getDirection() != 2) && (game.getSnake().First.Value.getDirection() != 0) && (game.getCommand() == true))
            {
                width = 0;
                height = -20;
                //game.head.setDirection(0);
                game.getSnake().First.Value.setDirection(0);
                game.setCommand(false);
            }
            if ((e.KeyCode == Keys.Down) && (game.getSnake().First.Value.getDirection() != 0) && (game.getSnake().First.Value.getDirection() != 2) && (game.getCommand() == true))
            {
                width = 0;
                height = 20;
                //game.head.setDirection(2);
                game.getSnake().First.Value.setDirection(2);
                game.setCommand(false);
            }
            if (e.KeyCode == Keys.A)
            {
                //add a new part of snake
                this.addPartData();//add it as data
                this.addPartPic();//add the picture
            }
            if (e.KeyCode == Keys.C)
            {
                //Start conection for multiplayer
                this.startMultiplayer();//add it as data                
            }
         
        }

        private void startMultiplayer()
        {
            Thread senderThread = new Thread(new ThreadStart(Multi.send));
            senderThread.IsBackground = true; // Test with or without the IsBackground property set to TRUE.
            senderThread.Start();
        }

        public void AdditionnalInitialization()
        {
            this.snakepic = new LinkedList<System.Windows.Forms.PictureBox>();

            //Adding the 3 default part
            this.snakepic.AddFirst(new System.Windows.Forms.PictureBox());//Head
            this.snakepic.AddLast(new System.Windows.Forms.PictureBox());//First body
            this.snakepic.AddLast(new System.Windows.Forms.PictureBox());//Tail

            // Adding the snake pictureboxes to panel1
            LinkedListNode<System.Windows.Forms.PictureBox> node3 = this.snakepic.First;
            while (node3 != null)
            {
                this.panel1.Controls.Add(node3.Value);
                node3 = node3.Next;
            }

            //Defining the settings of the snake pictureboxes
            LinkedListNode<System.Windows.Forms.PictureBox> node = this.snakepic.First;
            int i = 0;
            while (node != null)
            {

                if (i == 0) node.Value.BackColor = System.Drawing.Color.DarkGreen;
                else if (node.Next == null) node.Value.BackColor = System.Drawing.Color.DarkSlateGray;
                else node.Value.BackColor = System.Drawing.Color.Black;
                node.Value.Location = new System.Drawing.Point(260, 240 + 20 * i);
                node.Value.Name = "pictureBox" + i;
                node.Value.Size = new System.Drawing.Size(20, 20);
                node.Value.TabIndex = 0;
                node.Value.TabStop = false;
                i++;
                node = node.Next;
            }

            this.scoreLabel.Enabled = true;
            this.scoreLabel.Show();
        }



    }
}
